/*
* This file is part of Sensorium.
*
* Sensorium is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sensorium is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Sensorium. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*/
package at.univie.sensorium.extinterfaces;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import android.os.AsyncTask;
import android.util.Log;
import android.webkit.URLUtil;
import android.widget.Toast;
import at.univie.sensorium.SensorRegistry;
public class HTTPSUploader extends AsyncTask<List<File>, Void, String> {
private String posturl;
private String username;
private String password;
public HTTPSUploader(String posturl, String username, String password) {
this.posturl = posturl;
this.username = username;
this.password = password;
}
@Override
protected String doInBackground(List<File>... params) {
String result = uploadFiles(params[0]);
return "Sensorium: Upload finished with: " + result;
}
protected void onPostExecute(String result) {
Toast.makeText(SensorRegistry.getInstance().getContext(), result, Toast.LENGTH_SHORT).show();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(SensorRegistry.getInstance().getContext(), "Sensorium: Starting log upload.", Toast.LENGTH_SHORT).show();
}
private String uploadFiles(List<File> files) {
String result = "";
try {
if (URLUtil.isValidUrl(posturl)) {
HttpClient httpclient = getNewHttpClient();
HttpPost httppost = new HttpPost(posturl);
MultipartEntity mpEntity = new MultipartEntity();
// MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
mpEntity.addPart("username", new StringBody(username));
mpEntity.addPart("password", new StringBody(password));
for (File file : files) {
Log.d(SensorRegistry.TAG, "preparing " + file.getName() + " for upload");
ContentBody cbFile = new FileBody(file, "application/json");
mpEntity.addPart(file.toString(), cbFile);
}
httppost.addHeader("username", username);
httppost.addHeader("password", password);
httppost.setEntity(mpEntity);
HttpResponse response = httpclient.execute(httppost);
String reply;
InputStream in = response.getEntity().getContent();
StringBuilder sb = new StringBuilder();
try {
int chr;
while ((chr = in.read()) != -1) {
sb.append((char) chr);
}
reply = sb.toString();
} finally {
in.close();
}
result = response.getStatusLine().toString();
Log.d(SensorRegistry.TAG, "Http upload completed with response: " + result + " " + reply);
} else {
result = "URL invalid";
Log.d(SensorRegistry.TAG, "Invalid http upload url, aborting.");
}
} catch (IllegalArgumentException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
} catch (FileNotFoundException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
} catch (ClientProtocolException e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
} catch (IOException e) {
result = "upload failed due to timeout";
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.d(SensorRegistry.TAG, sw.toString());
}
return result;
}
public HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
int timeout = 10 * 1000;
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
private class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
final String ENABLED_CIPHERS[] = {
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_RC4_128_SHA",
"SSL_RSA_WITH_RC4_128_MD5",
};
final String ENABLED_PROTOCOLS[] = {
"TLSv1.2", "TLSv1.1", "TLSv1"
};
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
SSLSocket s = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
s.setEnabledProtocols(ENABLED_PROTOCOLS);
s.setEnabledCipherSuites(ENABLED_CIPHERS);
return s;
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}